package io.nads.mapper;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.nads.constant.RedisConstant;
import io.nads.context.BaseContext;
import io.nads.entity.ChatSession;
import io.nads.service.ChatSessionService;
import io.nads.service.ITTSService;
import io.nads.service.QWenService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static io.nads.constant.RedisConstant.EXPIRE_VOICE_KEY;

@Service
@Slf4j
public class ChatSessionServiceImpl implements ChatSessionService {
    @Autowired
    private ChatSessionMapper chatSessionMapper;

    @Autowired
    private QWenService qWenService;

    @Autowired
    private ITTSService ttsService;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 创建新的会话
     *
     * @param topic
     */
    public void createNewSession(String topic) {
        Long userId = BaseContext.getCurrentId();
        LocalDateTime now = LocalDateTime.now();
        List<String> voices = ttsService.getSupportedVoiceLabels();
        String getVoicePrompt = "请从列表中" + voices.toString() + "返回一个最接近主题:" + topic + "的下标，下标从0开始计数，下标不应该越界，即下标应该小于" + voices.size() + "你只需要返回一个数字，不需要返回其他的任何内容";
        String idxStr = qWenService.chat(getVoicePrompt);
        int idx = 0;
        try {
            idx = Integer.parseInt(idxStr);

        } catch (Exception e) {
            log.warn("大模型返回的下标格式错误");
        }
        String voice = ttsService.getSupportedVoices().get(idx);
        ChatSession chatSession = new ChatSession(null, userId, topic, now, now, voice);
        chatSessionMapper.insert(chatSession);
        BaseContext.setCurrentSessionId(chatSession.getId());
        // 将音色保存在缓存中
        String voiceKey = "voice:" + userId + ":" + BaseContext.getCurrentSessionId();
        redisTemplate.opsForValue().set(voiceKey, voice, EXPIRE_VOICE_KEY, TimeUnit.MINUTES);
        switchSessionContext(chatSession.getId());
    }

    /**
     * 更新会话
     *
     * @param chatSession 会话对象
     */
    @Override
    public void updateSession(ChatSession chatSession) {
        chatSession.setId(BaseContext.getCurrentSessionId());
        chatSessionMapper.updateById(chatSession);
    }

    @Override
    public void deleteSession(Long sessionId) {
        // 条件删除Session
        Long userId = BaseContext.getCurrentId();
        chatSessionMapper.delete(new QueryWrapper<ChatSession>().eq("id", sessionId).eq("user_id", userId));
    }

    /**
     * 查询所有会话
     *
     * @return 会话列表
     */
    @Override
    public List<ChatSession> selectAllSession() {
        return chatSessionMapper.selectList(new QueryWrapper<ChatSession>().eq("user_id", BaseContext.getCurrentId()));
    }

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    /**
     * 切换会话
     */
    @Override
    public void switchSessionContext(Long chatSessionId) {
        if (chatSessionId == null) {
            throw new RuntimeException("chatSessionId不能为空");
        }
        Long userId = BaseContext.getCurrentId();
        String idKey = RedisConstant.CHAT_SESSION_ID_KEY_PREFIX + userId;
        String topicKey = RedisConstant.CHAT_SESSION_TOPIC_KEY_PREFIX + userId;
        String voiceKey = RedisConstant.CHAT_SESSION_VOICE_KEY_PREFIX + userId;

        String sessionIdStr = stringRedisTemplate.opsForValue().get(idKey);
        if (sessionIdStr == null || !sessionIdStr.equals(chatSessionId.toString())) {
            // 更新或保存当前的sessionID以及音色
            stringRedisTemplate.opsForValue().set(idKey, chatSessionId.toString());
            // 从数据库中查询音色
            ChatSession chatSession = chatSessionMapper.selectById(chatSessionId);
            stringRedisTemplate.opsForValue().set(voiceKey, chatSession.getVoice());
            stringRedisTemplate.opsForValue().set(topicKey, chatSession.getTitle());
        }
        BaseContext.setCurrentSessionId(chatSessionId);
    }
}
